package com.nineclock.approve.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.nineclock.approve.pojo.ApproveDefinition;
import com.nineclock.approve.resolver.abs.ProcessNodeResolver;
import com.nineclock.approve.service.ActivitiService;
import com.nineclock.approve.utils.ActivitiUtils;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
@Slf4j
public class ActivitiServiceImpl implements ActivitiService {

    @Autowired
    private RepositoryService repositoryService;

    @Override
    public void deployProcessToActiviti(ApproveDefinition approveDefinition) {
        // 创建BpmnModel对象
        BpmnModel bpmnModel = new BpmnModel();

        // 创建process流程对象
        Process process = new Process();
        process.setId((ActivitiUtils.PROCESS_PREFIX + approveDefinition.getId()));
        process.setName(approveDefinition.getName());

        // 获取流程信息
        String flowJson = approveDefinition.getFlowJson();
        JSONArray jsonArray = JSON.parseArray(flowJson);

        // 添加节点到process
        addNodeToProcess(process, jsonArray);

        // 添加process到bpmnModel
        bpmnModel.addProcess(process);

        BpmnXMLConverter converter = new BpmnXMLConverter();
        byte[] bytes = converter.convertToXML(bpmnModel);
        log.info("动态构建BPMN模型，XML信息为" + new String(bytes));

        repositoryService.createDeployment().name(process.getName())
                .addBpmnModel(process.getName() + ".bpmn", bpmnModel)
                .deploy();

    }



    @Autowired
    private List<ProcessNodeResolver> resolverList;

    /**
     * 添加节点到process
     */
    private void addNodeToProcess(Process process, JSONArray jsonArray){

        for(int i = 0; i < jsonArray.size(); i++){

            // 获取当前节点
            JSONObject curNode = (JSONObject) jsonArray.get(i);

            // 获取下一个节点
            JSONObject nextNode = null;

            // 获取当前节点的类型
            String type = curNode.getString("type");

            // 跳过这类型
            if(type.equals("condition")){
                continue;
            }

            if(i < (jsonArray.size() - 1)){
                nextNode = (JSONObject) jsonArray.get(i + 1);
            }

            // 遍历所有的处理器，判断由哪个处理器处理
            for (ProcessNodeResolver resolver : resolverList) {
                // 如果判断为真，代表由该处理器进行处理
                if(resolver.support(type)){
                    resolver.addFlowNodeToActiviti(process, curNode, nextNode);
                }
            }

        }
    }

    @Override
    public void deleteProcessToActiviti(ApproveDefinition approveDefinition) {

        // 获取流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(
                ActivitiUtils.PROCESS_PREFIX + approveDefinition.getId()).singleResult();

        if(processDefinition!=null){
            // 删除已部署的流程定义信息
            repositoryService.deleteDeployment(processDefinition.getDeploymentId());
        }
    }
}
